<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /*
        Promise:
          1. 概念：异步编程解决方案，用来解决回调地狱问题

          2. promise有三种状态
            - pending 初始化
            - fulfilled 成功
            - rejected 失败

          当你new Promise构造函数，创建一个promise对象时，默认是pending状态，当你调用resolve方法，会将状态改为fulfilled，
          当你调用reject方法，会将状态改为rejected
          注意：状态只能改变一次，后面就不会在变化了

          3. promise对象上有三个方法：then / catch / finally
            then方法接受两个函数作为参数，当promise对象变成成功状态时，会触发第一个函数，当promise对象变成失败状态时，会触发第二个函数
            catch方法接受一个函数作为参数，当promise对象变成失败状态时，会这个函数
            finally方法接受一个函数作为参数，不管promise变成成功或失败，都会触发这个函数

            这个三个方法都返回一个新promise对象，所以使用时可以链式调用
            这个新promise对象的状态看对应方法执行的函数的结果：
              - 如果执行函数时报错了，返回新promise对象就是失败状态
              - 如果执行函数时返回一个promise对象，返回新promise对象的状态就是返回promise对象状态
              - 以上两个都没满足，就是成功状态

          4. Promise构造函数提供静态方法：
            Promise.resolve() 返回一个成功状态promise。（如果接受一个失败状态的promise, 那么就返回一个失败状态promise）
            Promise.reject() 返回一个失败状态promise
            Promise.all([promise1, promise2, ...]) 
              所有promise状态都变成成功状态，才返回一个成功状态的promise，只要有一个promise失败，就返回失败状态promise 
              只有所有成功才成功，只要有一个失败就失败
            Promise.allSettled([promise1, promise2, ...]) 
              等所有promise状态都发生了变化（不管成功还是失败），就返回一个成功状态promise
            Promise.race([promise1, promise2, ...])
              等所有promise中第一个状态发生变化的promise，就返回这个promise（不管成功或失败）
            Promise.any([promise1, promise2, ...])
              等所有promise中第一个成功状态的promise，就返回这个promise

          5. 使用场景 / 应用场景：
            一般在项目中使用axios发送请求会返回一个promise
            如果需要同时发送多个请求，可以使用Promise.allSettled方法完成
      */

      // const p1 = Promise.all([
      //   Promise.resolve(111),
      //   Promise.resolve(222),
      //   Promise.reject(333),
      // ]);
      // console.log(p1);

      // const p2 = Promise.allSettled([
      //   Promise.resolve(111),
      //   Promise.resolve(222),
      //   Promise.reject(333),
      // ]);
      // console.log(p2);

      // const p3 = Promise.race([
      //   Promise.reject(111),
      //   Promise.resolve(222),
      //   Promise.resolve(333),
      // ]);
      // console.log(p3);

      // const p4 = Promise.any([
      //   Promise.reject(111),
      //   Promise.resolve(222),
      //   Promise.resolve(333),
      // ]);
      // console.log(p4);

      const p = Promise.resolve();
      p.then(() => {
        console.log(1);
        console.log(hello); // hello is not define
      })
        .catch(() => {
          console.log(2);
        })
        .then(() => {
          console.log(3);
          return Promise.resolve(Promise.reject());
        })
        .catch(() => {
          console.log(4);
          return new Promise(() => {});
        })
        .then(() => {
          console.log(5);
          return new Promise(() => {});
        })
        .catch(() => {
          console.log(6);
        });
    </script>
  </body>
</html>
